package com.ruoyi.client.fxiaoke.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import com.ruoyi.client.core.service.ClientFormDataService;
import com.ruoyi.client.fxiaoke.beans.RecMessageBody;
import com.ruoyi.client.fxiaoke.service.CRMService;
import com.ruoyi.client.fxiaoke.service.FXiaoKeLocalService;
import com.ruoyi.client.fxiaoke.service.MessageManager;
import com.ruoyi.client.k3Cloud.service.K3CloudLocalService;
import com.ruoyi.core.api.util.PropertyUtil;
import com.ruoyi.core.bpm.util.BpmConst;
import com.ruoyi.core.util.UniqueIdUtil;
import com.ruoyi.platform.model.form.BpmFormData;
import com.ruoyi.platform.model.form.BpmFormField;
import com.ruoyi.platform.model.form.BpmFormTable;
import com.ruoyi.platform.model.form.PkValue;
import com.ruoyi.platform.model.form.SubTable;
import com.ruoyi.platform.model.system.K3CloudParameter;
import com.ruoyi.platform.service.form.BpmFormFieldService;
import com.ruoyi.platform.service.form.BpmFormHandlerService;
import com.ruoyi.platform.service.form.BpmFormTableService;

import net.sf.json.JSONObject;

@Service
public class FXiaoKeServiceImpl implements FXiaoKeLocalService {
	@Resource
	private CRMService crmService;
	@Resource
	private BpmFormHandlerService bpmFormHandlerService;
	@Resource
	private BpmFormTableService bpmFormTableService;
	@Resource
	private BpmFormFieldService bpmFormFieldService;
	@Resource
	private JdbcTemplate jdbcTemplate;
	@Resource
	private K3CloudLocalService k3CloudLocalService;
	@Resource
	private MessageManager messageManager;
	@Resource
	private ClientFormDataService clientFormDataService;
	/**
	 * 拉取crm数据
	 * @param apiName
	 * @param tableName
	 * @throws Exception
	 */
	public void downloadCRMData(String apiName,String tableName) throws Exception {
		downloadCRMData(apiName,tableName,tableName);
	}
	
	/**
	 * 拉取crm数据到本地
	 * @param apiName 预定义对象名称
	 * @param tableName 自定义表名
	 * @param formKey 自定义表单key
	 * @throws Exception
	 */
	public void downloadCRMData(String apiName,String tableName,String formKey) throws Exception {
		List<Map<String,Object>> dataList = crmService.getDataAll(apiName);
		
		BpmFormTable table = bpmFormTableService.getByTableName(tableName);
		
		Map<String,BpmFormField> fieldMap = getFieldMap(table);
		
		for (Map<String, Object> map : dataList) {
			map.put("fxiaoke_pk", map.get("_id"));
			Map<String,Object> mainMap = bpmFormHandlerService.handMap(table, fieldMap, map);
			mainMap = convert(mainMap);
			
			//设置主键
			Long id = getPkValue(tableName,map.get("_id").toString());
			PkValue pkValue = new PkValue();
			pkValue.setIsAdd(false);
			if(id == 0L) {
				pkValue.setIsAdd(true);
				id = UniqueIdUtil.genId();
			}
			pkValue.setName(table.getPkField());
			pkValue.setValue(id);
			
			mainMap.put(table.getPkField(), id);
			BpmFormData bpmFormData = new BpmFormData();
			bpmFormData.setBpmFormTable(table);
			bpmFormData.setSubTableList(new ArrayList<SubTable>());
			bpmFormData.setTableId(table.getTableId());
			bpmFormData.setMainFields(mainMap);
			
			
			
			bpmFormData.setPkValue(pkValue);
			
			bpmFormHandlerService.handFormData(bpmFormData, formKey, "");
			Thread.sleep(1000L);
		}
	}
	
	/**
	 * 设置子表数据
	 * @param bpmFormData
	 * @param pkField
	 * @throws Exception
	 */
	public void setSubData(BpmFormData bpmFormData,Map<String,String> pkField) throws Exception {
		List<SubTable> subTableDataList = new ArrayList<SubTable>();
		
		BpmFormTable table = bpmFormData.getBpmFormTable();
		List<BpmFormTable> subTableList = table.getSubTableList();
		//获取主键和纷享销客主键
		String refId = bpmFormData.getMainField("f_fxiaoke_pk").toString();
		String mainId = bpmFormData.getPkValue().getValue().toString();
		
		//设置子表值
		for (BpmFormTable bpmFormTable : subTableList) {
			String tableName = bpmFormTable.getTableName();
			if(!pkField.containsKey(tableName))continue;
			String apiName = tableName.replace("FXiaoKe_", "");
			String pkName = pkField.get(tableName);
			
			//获取纷享销客字表数据
			List<Map<String,Object>> dataList = crmService.getByRefId(apiName, pkName, refId);
			
			SubTable subTable = new SubTable();
			subTable.setFkName(bpmFormTable.getRelation());
			subTable.setPkName(bpmFormTable.getPkField());
			subTable.setTableName(tableName);
			subTable.setDataList(new ArrayList<Map<String,Object>>());
			//设置子表值
			Map<String,BpmFormField> fieldMap = getFieldMap(bpmFormTable);
			for (Map<String, Object> dataMap : dataList) {
				dataMap.put("fxiaoke_pk", dataMap.get("_id"));
				Map<String,Object> rowMap = bpmFormHandlerService.handMap(bpmFormTable, fieldMap, dataMap);
				rowMap = convert(rowMap);
				
				Long id = 0L;
				if(fieldMap.containsKey("fxiaoke_pk") && !bpmFormData.getPkValue().getIsAdd()) {
					id = this.getPkValue(tableName, dataMap.get("_id").toString());
				}
				if(id == 0L) {
					id = UniqueIdUtil.genId();
				}
				
				
				
				rowMap.put(bpmFormTable.getRelation(), mainId);
				rowMap.put(bpmFormTable.getPkField(), id);
				subTable.addRow(rowMap);
			}
			
			subTableDataList.add(subTable);
		}
		
		bpmFormData.setSubTableList(subTableDataList);
	}
	
	/**
	 * 事件
	 * @param msgBody
	 * @throws Exception
	 */
	public void event(RecMessageBody msgBody) throws Exception {
		String apiName = msgBody.getApiName();
		String eventType = msgBody.getEventType();
		String dataId = msgBody.getDataId();
		
		String tableName = "FXiaoKe_"+apiName;
		
		//判断表是否存在
		if(!bpmFormTableService.isTableNameExisted(tableName)) {
			Map<String,Object> model = crmService.getApiModel(apiName);
			if(model == null)return;
			
			Object desc = model.get("describeDisplayName");
			messageManager.sendTextMsgToAdmin("未实现该对象同步接口:"+desc);
			return;
		}
		
		if("insert".equals(eventType) || "update".equals(eventType)) {
			save(apiName,dataId);
			return;
		}
		
		if("delete".equals(eventType)) {//删除
			Long pk = getPkValue(tableName,dataId);
			//删除金蝶数据
			if(PropertyUtil.getBooleanByAlias(K3CloudParameter.K3CLOUD_SupportK3cloud,false)) {
				k3CloudLocalService.delete(pk.toString());
			}
			bpmFormHandlerService.delByIdTableName(pk.toString(), "W_"+tableName);
			return;
		}
		
		Map<String,Object> data = crmService.getById(apiName, dataId);
		Long pk = getPkValue(tableName,data.get("_id").toString());
		
		if("invalid".equals(eventType)) {//作废
			//禁用金蝶数据
			if(PropertyUtil.getBooleanByAlias(K3CloudParameter.K3CLOUD_SupportK3cloud,false)) {
				k3CloudLocalService.excuteOperation(pk.toString());
			}
			
		}else if("recover".equals(eventType)) {//恢复
			//恢复金蝶数据
			if(PropertyUtil.getBooleanByAlias(K3CloudParameter.K3CLOUD_SupportK3cloud,false)) {
				k3CloudLocalService.unExcuteOperation(pk.toString());
			}
			
		}
		
		//BpmFormTable table = bpmFormTableService.getByTableName("FXiaoKe_"+apiName);
		//Map<String,BpmFormField> fieldMap = getFieldMap(table.getTableId());
	}
	
	/**
	 * 获取业务主键
	 * @param tableName
	 * @param dataId
	 * @return
	 */
	private Long getPkValue(String tableName,String dataId) {
		String pk = "";
		try {
			pk = jdbcTemplate.queryForObject("select ID from W_"+tableName + " where F_fxiaoke_pk='"+dataId+"'", String.class);
			return Long.parseLong(pk);
		} catch (DataAccessException e) {
			return 0L;
		}
	}
	
	/**
	 * 添加，更新表单数据
	 * @param apiName
	 * @throws Exception 
	 */
	public void save(String apiName,String dataId) throws Exception {
		Map<String,Object> data = crmService.getById(apiName, dataId);
		data.put("fxiaoke_pk", data.get("_id"));
		String formKey = "FXiaoKe_"+apiName;
		clientFormDataService.saveFormData(formKey, "fxiaoke_pk", "_id", data);
	}
	
	/**
	 * 添加，更新表单数据
	 * @param apiName
	 * @throws Exception 
	 */
	public void save(String apiName,Map<String,Object> data) throws Exception {
		data.put("fxiaoke_pk", data.get("_id"));
		String tableName = "FXiaoKe_"+apiName;
		
		BpmFormTable table = bpmFormTableService.getByTableName(tableName);
		
		
		Map<String,BpmFormField> fieldMap = getFieldMap(table);
		Long pk = getPkValue(tableName,data.get("_id").toString());
		boolean isAdd = true;
		if(pk != 0L) {
			isAdd = false;
		}else {
			pk = UniqueIdUtil.genId();
		}
		//设置主键对象
		PkValue pkValue = new PkValue();
		pkValue.setIsAdd(isAdd);
		pkValue.setName("ID");
		pkValue.setValue(pk);
		
		//添加表单数据
		Map<String,Object> mainMap = bpmFormHandlerService.handMap(table, fieldMap, data);
		mainMap = convert(mainMap);
		mainMap.put("ID", pk);
		BpmFormData bpmFormData = new BpmFormData();
		bpmFormData.setBpmFormTable(table);
		bpmFormData.setSubTableList(new ArrayList<SubTable>());
		bpmFormData.setTableId(table.getTableId());
		bpmFormData.setMainFields(mainMap);
		bpmFormData.setPkValue(pkValue);
		
		bpmFormHandlerService.handFormData(bpmFormData, tableName, "");
	}
	
	private Map<String,Object> convert(Map<String, Object> map){
		Map<String,Object> filedMap = new HashMap<>();
		for(Entry<String,Object> entry: map.entrySet()) {
			Object v = entry.getValue();
			filedMap.put("f_" + entry.getKey().toLowerCase(), v ==null?"":v.toString());
		}
		return filedMap;
	}
	
	private Map<String,BpmFormField> getFieldMap(BpmFormTable table){
		Map<String,BpmFormField> fieldMap = new HashMap<>();
		List<BpmFormField> fieldList = table.getFieldList();
		for (BpmFormField bpmFormField : fieldList) {
			fieldMap.put(bpmFormField.getFieldName(), bpmFormField);
		}
		return fieldMap;
	}

	@Override
	public void updataPk(String tableName, String pkName, String pkValue,Object id) {
		jdbcTemplate.update("update W_"+tableName + " set F_"+pkName + "='"+pkValue + "' where id='" + id + "'");
	}

	@Override
	public String getPk(String tableName, String pkName, Object id) {
		try {
			return jdbcTemplate.queryForObject("select F_" + pkName + " from W_" + tableName + " where ID='"+id+"'", String.class);
		} catch (DataAccessException e) {
			return "0";
		}
	}
}
